/*
 * Copyright 2011-2012 by The Regents of the University of California Licensed
 * under the Apache License, Version 2.0 (the "License"); you may not use this
 * file except in compliance with the License. you may obtain a copy of the
 * License from
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package edu.ucsd.db.bassarisk.schema;

import java.util.logging.Logger;

import edu.ucsd.db.bassarisk.schema.Schema.Cardinality;
import edu.ucsd.db.bassarisk.schema.Schema.ValueType;

public class SchemaBuilder {
  private final Logger LOG = Logger.getLogger(this.getClass().getName());
  private final SchemaRootNode schema;

  public SchemaBuilder() {
    this.schema = new SchemaRootNode();
  }

  private void addNodeAtPath(final SchemaNode node, final String[] path) {
    SchemaRunNode parent = Schema.findAtSimplePath(this.schema, path);
    if (parent != null) {
      parent.addChild(node);
    } else {
      String pathString = "";
      for (String pathTag : path) {
        pathString += "/" + pathTag;
      }
      String message =
          "Schema element %s could not be inserted because of error while finding "
              + "parent schema element at %s.";
      this.LOG.warning(String.format(message, node.getName(), pathString));
    }
  }

  public void addPositionAttribute(final String tag, final Cardinality c,
                                   final ValueType vt) {
    SchemaPositionAttributeNode newNode =
        new SchemaPositionAttributeNode(tag, c, vt);
    this.schema.addChild(newNode);
  }

  public void addRun(final String name, final Cardinality c, final String[] path) {
    SchemaRunNode newNode = new SchemaRunNode(name, c);
    newNode.children.add(new SchemaRunAttributeNode("start", Cardinality.One,
                                                    ValueType.Int64));
    newNode.children.add(new SchemaRunAttributeNode("length", Cardinality.One,
                                                    ValueType.Int64));
    this.addNodeAtPath(newNode, path);
  }

  public void addRunAttribute(final String tag, final Cardinality c,
                              final ValueType vt, final String[] path) {
    SchemaRunAttributeNode newNode = new SchemaRunAttributeNode(tag, c, vt);
    this.addNodeAtPath(newNode, path);
  }

  public SchemaRootNode getSchema() {
    return this.schema;
  }
}
